/**
 * 类名：MSWord
 * 创建日期： 2014-10-26 下午8:06:41
 * 
 */
package com.erms.util.office;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.InputStream;
import java.util.List;

import javax.xml.parsers.DocumentBuilderFactory;

import org.apache.poi.hwpf.HWPFDocument;
import org.apache.poi.hwpf.converter.PicturesManager;
import org.apache.poi.hwpf.converter.WordToHtmlConverter;
import org.apache.poi.hwpf.usermodel.Picture;
import org.apache.poi.hwpf.usermodel.PictureType;
import org.docx4j.Docx4J;
import org.docx4j.convert.out.HTMLSettings;
import org.docx4j.fonts.IdentityPlusMapper;
import org.docx4j.fonts.Mapper;
import org.docx4j.fonts.PhysicalFont;
import org.docx4j.fonts.PhysicalFonts;
import org.docx4j.openpackaging.packages.WordprocessingMLPackage;
import org.w3c.dom.Document;

/**
 * @author hmb
 *         备注：
 * 
 */
public class MSWord extends MSOffice {

	/**
	 * @param inputFileName
	 */
	public MSWord(String inputFileName) {

		super(inputFileName);
	}

	public MSWord(String inputFileName, String encoding) {

		super(inputFileName, encoding);
	}

	/**
	 * WORD 转 HTML，不保存html文件
	 * 
	 * @return 转化后的html字符串
	 */
	public String toHtml() {

		return toHtml(null);
	}

	/**
	 * 
	 * Word 转 html，同时保存html到指定文件中
	 * 
	 * @param outputFile 如果不保存为文件则为null
	 * @return 转化后的html字符串
	 */
	public String toHtml(String outputFile) {

		// TODO 自动生成的方法存根

		this.outputFile = outputFile;

		if (this.outputFile != null && this.outputFile.startsWith("/")) {
			logger.debug("输出文件不能为绝对路径");
			this.outputFile = outputFile.substring(1);
		}

		logger.debug("输出文件:" + rootPath + this.outputFile);

		if (inputFile.endsWith(".doc")) {
			return toHtmlWithDoc();
		} else if (inputFile.endsWith(".docx")) {
			return toHtmlWithDocx();
		} else {
			logger.debug("暂不支持的word格式");
		}

		return "暂不支持的word格式";
	}

	private String toHtmlWithDoc() {

		try {

			InputStream is = new FileInputStream(this.inputFile);

			HWPFDocument wordDocument = new HWPFDocument(is);
			is.close();

			WordToHtmlConverter wordToHtmlConverter = new WordToHtmlConverter(
					DocumentBuilderFactory.newInstance().newDocumentBuilder()
							.newDocument());

			wordToHtmlConverter.setPicturesManager(new PicturesManager() {
				public String savePicture(byte[] content,
						PictureType pictureType, String suggestedName,
						float widthInches, float heightInches) {

					logger.debug("图片信息--建议名:" + suggestedName + ";类型:"
							+ pictureType + ";分辨率:" + widthInches + "x"
							+ heightInches);
					// TODO 这里需要修改word文档中图片路径生成规则
					return "temp/img/" + suggestedName;
				}
			});

			wordToHtmlConverter.processDocument(wordDocument);
			List<Picture> pics = wordDocument.getPicturesTable()
					.getAllPictures();
			if (pics != null) {
				for (int i = 0; i < pics.size(); i++) {
					Picture pic = pics.get(i);
					try {
						// TODO 这里需要修改word文档中图片路径生成规则
						File file = new File(rootPath + "/img/"
								+ pic.suggestFullFileName());
						if (!file.exists()) {
							file.getParentFile().mkdirs();

						}
						pic.writeImageContent(new FileOutputStream(file));
					} catch (FileNotFoundException e) {
						logger.error("解析word中的图片时出错", e);
					}
				}
			}
			Document htmlDocument = wordToHtmlConverter.getDocument();

			String html = saveAsHtml(htmlDocument);

			return html;
		} catch (Exception e) {
			logger.error("toHtml:word转html失败", e);
		}

		return "";
	}

	private String toHtmlWithDocx() {

		try {
			InputStream is = new FileInputStream(this.inputFile);
			WordprocessingMLPackage wmp = Docx4J.load(is);

			ByteArrayOutputStream out = new ByteArrayOutputStream();
			HTMLSettings settings = new HTMLSettings();
			settings.setWmlPackage(wmp);
			settings.setImageDirPath(rootPath + "/img/");
			settings.setImageTargetUri("temp/img/");
			Mapper fontMapper = new IdentityPlusMapper();
			
			PhysicalFont font = PhysicalFonts.get("SimSun");
			if (font != null) {
				fontMapper.put("仿宋_GB2312", font);
				fontMapper.put("Arial", font);
				fontMapper.put("Times New Roman", font);
			}
			settings.setFontMapper(fontMapper);
			//settings.setFontFamilyStack(true);
		/*	String userCSS = "html, body, div, span, h1, h2, h3, h4, h5, h6, p, a, img,  ol, ul, li, table, caption, tbody, tfoot, thead, tr, th, td " +
	    			"{ margin: 0; padding: 0; border: 0;}" +
	    			"body {line-height: 1;} ";
	    	settings.setUserCSS(userCSS);*/
			Docx4J.toHTML(settings, out, Docx4J.FLAG_EXPORT_PREFER_NONXSL);

			String html = out.toString(this.encoding);
			if (outputFile != null) {
				FileWriter writer = new FileWriter(rootPath + outputFile);
				writer.write(html);
				writer.close();
			}
			
			return html;
		} catch (Exception e) {
			// TODO 自动生成的 catch 块
			logger.error("toHtmlWithDocx1 + FileNotFoundException", e);
		}
		return null;
	}
	
	public static void main(String[] args) {
		MSWord doc = new MSWord("d:/test/test1.doc");
		MSWord doc1 = new MSWord("d:/test/test1.doc");
		MSWord docx = new MSWord("d:/test/test1.docx");
		MSWord docx1 = new MSWord("d:/test/test1.docx");
		toHtml(doc, "doc1.html");
		toHtml(doc1, "doc1.html");
		toHtml(docx, "docx1.html");
		toHtml(docx1, "docx1.html");
	}
	private static void toHtml(MSWord word,String path) {

		long oldTime = System.currentTimeMillis();
		word.toHtml(path);
		System.out.println(path+" 共用时："+(System.currentTimeMillis() - oldTime) + "ms");
	}
	/*private String toHtmlWithDocx() {

		// TODO 实现word2007以上版本文档的转化
		try {
			final String HtmlName = rootPath + this.outputFile;
			InputStream is = new FileInputStream(new File(this.inputFile));
			XWPFDocument document = new XWPFDocument(is);

			// 2) Prepare Html options
			XHTMLOptions options = XHTMLOptions.create().indent(4);
			// options.setFragment(true);
			options.setIgnoreStylesIfUnused(false);
			options.setOmitHeaderFooterPages(true);

			options.setExtractor(new IImageExtractor() {

				@Override
				public void extract(String imagePath, byte[] imageData)
						throws IOException {

					// TODO 这里需要保存图片
					logger.debug("图片名：" + imagePath);
					File imgFile = new File(rootPath + imagePath);
					if (!imgFile.exists()) {
						imgFile.getParentFile().mkdirs();
					}
					OutputStream out = new FileOutputStream(imgFile);
					out.write(imageData);
					out.close();

				}
			});
			options.URIResolver(new IURIResolver() {

				@Override
				public String resolve(String uri) {

					// TODO 这里需要转化图片连接地址，对应上面的图片，默认为word/media/imageX.jpg X为数字
					logger.debug("uri:" + uri);
					return uri;
				}
			});
			// 3) Convert XWPFDocument to HTML
			ByteArrayOutputStream out = new ByteArrayOutputStream();
			XHTMLConverter.getInstance().convert(document, out, options);
			is.close();

			if (this.outputFile != null) {
				FileWriter fileWriter = new FileWriter(HtmlName);
				fileWriter.write(out.toString(encoding));
				fileWriter.close();
			}
			return out.toString(encoding);
		} catch (Exception e) {
			logger.error("toHtml:word转html失败", e);
		}

		return "";
	}*/

	/*public boolean toPDF(String outputFile) throws Exception {

		InputStream is = new FileInputStream(new File(this.inputFile));
		XWPFDocument document = new XWPFDocument(is);

		// 2) Prepare Pdf options
		PdfOptions options = PdfOptions.create();

		// 3) Convert XWPFDocument to Pdf
		OutputStream out = new FileOutputStream(new File(rootPath + outputFile));
		PdfConverter.getInstance().convert(document, out, options);
		return false;
	}*/
}
